package org.gtiles.components.login.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gtiles.components.configuration.LoginConfigurationProperties;
import org.gtiles.components.login.authentication.CustomUserDatails;
import org.gtiles.components.login.authentication.IAuthenticatedUser;
import org.gtiles.components.login.service.IPostHandlerAction.IPostHandlerAction;
import org.gtiles.components.login.web.DefaultLoginJsonRenderImpl;
import org.gtiles.components.login.web.ILoginJsonRender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 通过URL中的“login_ct”参数进行判断。
 * <code>if (login_ct != null && login_ct.equals("ajax"))</code>
 * ,仅返回登录成功的json，反之按spring security原有逻辑跳转相关的URL请求<br>
 * 1、可以通过修改系统参数中的“plugins_login_jsonRenderBean”来扩展“login_ct”请求返回的json内容；<br>
 * 2、可以通过修改系统参数中的“plugins_login_successPostActionBean”来扩展完成登录成功后的业务处理；<br>
 * 3、可以通过修改系统参数中的“plugins_login_alwaysUseDefaultTargetUrl”
 * 来配置是否登录成功后固定跳转到defaultTargetUrl路径；<br>
 * 4、可以通过修改系统参数中的“plugins_login_defaultTargetUrl”来指定登录成功后跳转的路径；<br>
 * 5、可以通过修改系统参数中的“plugins_login_targetUrlParameter”来指定登录成功的路径默认带的参数值；<br>
 * <br>
 * 
 * @author GuoR
 */
public class CustomAuthenticationSuccessHandler extends
		SimpleUrlAuthenticationSuccessHandler {
	protected final Log logger = LogFactory.getLog(this.getClass());
	@Autowired
	private LoginConfigurationProperties loginConfigurationProperties;

	public CustomAuthenticationSuccessHandler(
			LoginConfigurationProperties loginConfigurationProperties) {
		super();
		this.loginConfigurationProperties = loginConfigurationProperties;
		logger.info("===========>"+this.loginConfigurationProperties.toString());
	}

	@Override
	protected void handle(HttpServletRequest request,
			HttpServletResponse response, Authentication authentication)
			throws IOException, ServletException {
		initParam();
		// 获取登录方式参数
		// String clientType = request.getParameter("login_ct");
		CustomUserDatails customUserDatails = (CustomUserDatails) authentication
				.getPrincipal();
		IAuthenticatedUser authenticationImpl = (IAuthenticatedUser) customUserDatails
				.getExtendAccountInfo();
		request.getSession().setAttribute(IAuthenticatedUser.SESSION_ATTRNAME,
				authenticationImpl);
		ObjectMapper objectMapper = new ObjectMapper();
		String userJsonStr = objectMapper
				.writeValueAsString(authenticationImpl);
		request.getSession().setAttribute("USER_JSON", userJsonStr);
		String targetUrl = determineTargetUrl(request, response);

		// String postActionBean = (String) ConfigHolder.getConfigValue(
		// ComponentPlugin.PLUGIN_CODE,
		// "plugins_login_successPostActionBean");
		// String jsonRenderBean = (String) ConfigHolder.getConfigValue(
		// ComponentPlugin.PLUGIN_CODE,
		// "plugins_login_jsonRenderBean");
		// Assert.notNull(jsonRenderBean, "jsonRenderBean cannot be null");
		String[] successPostActionBean = loginConfigurationProperties.getSuccessPostActionBean();
		if (successPostActionBean != null
				&& successPostActionBean.length > 0) {
			for (int i = 0, j = successPostActionBean.length; i < j; i++) {
				Class<?> forName;
				try {
					forName = Class.forName(successPostActionBean[i]);
					IPostHandlerAction postAction = (IPostHandlerAction) forName.newInstance();
					postAction.loginPostHandler(request, response);
				} catch (ClassNotFoundException e) {
					throw new ServletException("ClassNotFoundException:"+e.getMessage());
				} catch (Exception e) {
					e.printStackTrace();
					throw new ServletException("登录后处理初始化异常，请检查配置文件及是否为IPostHandlerAction的实现类");
				} 
			}
		}
		// 仅对AJAX的请求，返回登录成功的json信息
		if (StringUtils.hasText(targetUrl) && targetUrl.equals("ajax")) {
			try {
				// FIXME 暂时写死实现类，下次迭代将它变成可配置的
				ILoginJsonRender jsonRender = new DefaultLoginJsonRenderImpl();
				jsonRender.loginSuccess(request, response);
			} catch (Exception e) {
				throw new RuntimeException(
						"登录json格式数据处理类实例化失败，请检查相关参数配置及接口实现是否正确。", e);
			}
		} else {
			getRedirectStrategy().sendRedirect(request, response, targetUrl);
		}
	}

	protected void initParam() {
		// String alwaysUseDefaultTargetUrl = (String) ConfigHolder
		// .getConfigValue(
		// ComponentPlugin.PLUGIN_CODE,
		// "plugins_login_alwaysUseDefaultTargetUrl");
		// if (!StringUtils.isEmpty(alwaysUseDefaultTargetUrl)) {
		// boolean alwaysUseDefaultTargetUrlBoolean = false;
		// try {
		// //FIXME 修改booleanUtils的调用方法，是否需要提升到平台的工具类中？
		// alwaysUseDefaultTargetUrlBoolean = BooleanUtils
		// .parseBoolean(alwaysUseDefaultTargetUrl);
		// } catch (IllegalArgumentException e) {
		// logger.error(e.getMessage(), e);
		// }
		// super.setAlwaysUseDefaultTargetUrl(alwaysUseDefaultTargetUrlBoolean);
		// }
		// String defaultTargetUrl = (String) ConfigHolder
		// .getConfigValue(
		// ComponentPlugin.PLUGIN_CODE,
		// "plugins_login_defaultTargetUrl");
		// if (!StringUtils.isEmpty(defaultTargetUrl)) {
		// super.setDefaultTargetUrl(defaultTargetUrl);
		// }
		// String targetUrlParameter = (String) ConfigHolder
		// .getConfigValue(
		// ComponentPlugin.PLUGIN_CODE,
		// "plugins_login_targetUrlParameter");
		String targetUrlParameter = "login_ct";
		if (!StringUtils.isEmpty(targetUrlParameter)) {
			super.setTargetUrlParameter(targetUrlParameter);
		}
	}
}
